import requests
import time
import urllib.parse

# GitHub Token（可选，强烈建议使用以避免限流）
TOKEN = ""  # 替换为你的 GitHub Personal Access Token
HEADERS = {
    "Authorization": f"token {TOKEN}" if TOKEN else None,
    "Accept": "application/vnd.github.v3+json"
}

def search_exact_filename_files():
    # 用户输入文件名
    filename = input("请输入要搜索的文件名（例如：main.py, Dockerfile, config.json）: ").strip()
    if not filename:
        print("文件名不能为空！")
        return

    print(f"\n🔍 正在搜索 GitHub 上的精确文件名: {filename}")
    print("✅ 使用精确文件名匹配（排除 main.py.bak 等变体）\n")

    url = "https://api.github.com/search/repositories"
    # 使用 GitHub 搜索语法：path:/ 确保是根目录或任意路径，但 filename 精确匹配
    query = f"filename:{urllib.parse.quote(filename)} path:/"  # path:/ 提高文件名匹配精度
    params = {
        "q": query,
        "sort": "stars",
        "order": "desc",
        "per_page": 30  # 可改到 100
    }

    response = requests.get(url, headers=HEADERS, params=params)

    if response.status_code != 200:
        print("❌ GitHub API 错误:", response.json())
        return

    repos = response.json().get("items", [])
    if not repos:
        print("🔍 没有找到包含该文件的仓库。")
        return

    print(f"📦 找到 {len(repos)} 个包含 '{filename}' 的仓库（按 stars 排序）：\n")
    download_links = []

    for repo in repos:
        repo_name = repo["full_name"]
        stars = repo["stargazers_count"]

        # Step 1: 使用 GitHub Contents API 获取文件信息（精确匹配）
        api_url = f"https://api.github.com/repos/{repo_name}/contents"
        contents_response = requests.get(f"{api_url}/", headers=HEADERS)

        if contents_response.status_code != 200:
            print(f"⚠️ 无法访问仓库内容: {repo_name}")
            continue

        try:
            all_items = contents_response.json()
            if isinstance(all_items, dict):  # 可能是错误
                continue
        except:
            continue

        # 递归查找精确匹配的文件名（只匹配完整文件名）
        found = False
        for item in all_items:
            if item["type"] == "file" and item["name"] == filename:
                found = True
                break
            elif item["type"] == "dir" and item["name"] in [".", "..", "_", "test", "tests", "docs"]:
                continue  # 可选：跳过某些目录
        else:
            # 如果根目录没找到，尝试用搜索 API 精确查找
            search_file_url = f"https://api.github.com/search/code"
            q = f"repo:{repo_name} filename:{filename}"
            search_resp = requests.get(search_file_url, headers=HEADERS, params={"q": q})
            if search_resp.status_code == 200:
                results = search_resp.json().get("items", [])
                for result in results:
                    if result["name"] == filename:
                        found = True
                        break

        if not found:
            continue  # 跳过不精确匹配的

        # Step 2: 构造 raw 链接（尝试 main 和 master 分支）
        for branch in ["main", "master"]:
            raw_url = f"https://raw.githubusercontent.com/{repo_name}/{branch}/{filename}"
            # 使用 HEAD 检查是否存在（避免返回 404 链接）
            head_resp = requests.head(raw_url, headers=HEADERS)
            if head_resp.status_code == 200:
                download_url = raw_url
                github_blob_url = f"https://github.com/{repo_name}/blob/{branch}/{filename}"
                download_links.append({
                    "repo": repo_name,
                    "stars": stars,
                    "url": github_blob_url,
                    "download_url": download_url
                })
                print(f"✅ {stars:>6} ⭐ | {repo_name}")
                print(f"     🌐 {github_blob_url}")
                print(f"     ⬇️  {download_url}\n")
                break
        else:
            print(f"❌ {repo_name}: 找到文件但无法确认分支中存在 '{filename}'\n")

        time.sleep(0.5)  # 避免限流

    # 最终只输出所有下载链接
    print(f"✅ 总共找到 {len(download_links)} 个精确匹配的 '{filename}' 下载链接：\n")
    for item in download_links:
        print(item["download_url"])

search_exact_filename_files()
